{
  // ------------------------------------------类的装饰器
  //装饰器本身就是一个函数
  //装饰器通过 @ 符号来使用

  // 使用装饰器 tsconfig.json 文件配置要打开
  // "experimentalDecorators": true,
  // "emitDecoratorMetadata": true,

  function testDecoretor() {
    return function <T extends new (...args: any[]) => any>(constructor: T) {
      return class extends constructor {
        name = 'less'
        getName() {
          return this.name
        }
      }
    }
  }

  //-------先执行的 Test 这个构造函数  在去执行拓展的类
  const Test = testDecoretor()(
    class {
      name: string
      constructor(name: string) {
        this.name = name
      }
    }
  )

  const test = new Test('dell')
  // console.log(test.getName(), '>?????')
}

// -------------------------------------方法的装饰器
{
  //普通方法 target   对应的是类的 prototype
  //静态方法 target   对应的是类的构造函数
  // 三个参数  1、对象  2、属性 3、descriptor
  function getNameDecorator(
    target: any,
    key: string,
    descriptor: PropertyDescriptor
  ) {
    console.log(target, 'target', key)
    //不能改写test.getName 的方法
    // descriptor.writable = true;
    descriptor.value = function () {
      return '更改了1'
    }
  }
  class Test {
    name: string
    constructor(name: string) {
      this.name = name
    }
    @getNameDecorator
    getName() {
      return this.name
    }
  }

  const test = new Test('dell')

  console.log(test.getName())
}
